package fr.dauphine.bookstore.frontoffice;

import java.io.IOException;
import java.util.Collection;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanPropertyValueEqualsPredicate;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;

import fr.dauphine.bookstore.commun.MessagesUtil;
import fr.dauphine.bookstore.hibernate.HibernateUtil;
import fr.dauphine.bookstore.modele.Book;
import fr.dauphine.bookstore.modele.User;

/**
 * Sauvegarde les modifications de l'utilisateur sur son compte.
 */
public final class SaveAccountServlet extends HttpServlet {

	/**
	 * Serial version UID.
	 */
	private static final long serialVersionUID = -247482580033564928L;

	/**
	 * Pour la conversion en Ko.
	 */
	private static final int SIZE_CONVERT = 1024;

	/**
	 * Traite la methode POST.
	 * 
	 * @param request
	 *            Requete
	 * @param response
	 *            Reponse
	 * @throws ServletException
	 *             Erreur de servlet
	 * @throws IOException
	 *             Erreur d'entree/sortie
	 */
	@SuppressWarnings("unchecked")
	protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
		User user = SessionUtil.getUserEdition(request.getSession());

		ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
		Collection<FileItem> items = null;
		try {
			items = upload.parseRequest(request);

		} catch (FileUploadException e) {
			throw new ServletException(e.getMessage());
		}

		retreivePassword(request, items, user);
		retreiveLastName(request, items, user);
		retreiveFirstName(request, items, user);
		retreiveEmail(request, items, user);
		retreiveAvatar(request, items, user);

		// On sauvegarde
		if (!MessagesUtil.isThereErrors(request)) {

			// Si l'utilisateur a rempli le champ mot de passe, il veut le modifier
			// => Hash du mot de passe
			if (StringUtils.isNotEmpty(user.getPassword())) {
				user.setPassword(DigestUtils.md5Hex(user.getPassword()));
			
			// Il ne l'a pas rempli, on le recupere depuis l'objet en session
			} else {
				User connectedUser = SessionUtil.getUser(request.getSession());
				user.setPassword(connectedUser.getPassword());
			}

			Session hSession = HibernateUtil.getSessionFactory().getCurrentSession();
			hSession.update(user);

			SessionUtil.setUser(request.getSession(), user);

			response.sendRedirect("index.jsp");

			// On retourne sur la page de modification
		} else {
			request.getRequestDispatcher("account.jsp").forward(request, response);
		}
	}

	/**
	 * Recupere l'email dans la liste d'items.
	 * 
	 * @param request
	 *            Requete
	 * @param items
	 *            Liste d'items
	 * @param user
	 *            Utilisateur en cours de modification
	 */
	private void retreiveEmail(final HttpServletRequest request, final Collection<FileItem> items, final User user) {
		FileItem item = (FileItem) CollectionUtils.find(items, new BeanPropertyValueEqualsPredicate("fieldName", "email"));

		user.setEmail(item.getString());

		if (StringUtils.isEmpty(user.getEmail())) {
			MessagesUtil.addMessage(request, MessagesUtil.ERROR, "L'adresse e-mail est obligatoire");
		}
	}

	/**
	 * Recupere le nom dans la liste d'items.
	 * 
	 * @param request
	 *            Requete
	 * @param items
	 *            Liste d'items
	 * @param user
	 *            Utilisateur en cours de modification
	 */
	private void retreiveLastName(final HttpServletRequest request, final Collection<FileItem> items, final User user) {
		FileItem item = (FileItem) CollectionUtils.find(items, new BeanPropertyValueEqualsPredicate("fieldName", "lastName"));

		user.setLastName(item.getString());

		if (StringUtils.isEmpty(user.getLastName())) {
			MessagesUtil.addMessage(request, MessagesUtil.ERROR, "Le nom est obligatoire");
		}
	}

	/**
	 * Recupere le prenom dans la liste d'items.
	 * 
	 * @param request
	 *            Requete
	 * @param items
	 *            Liste d'items
	 * @param user
	 *            Utilisateur en cours de modification
	 */
	private void retreiveFirstName(final HttpServletRequest request, final Collection<FileItem> items, final User user) {
		FileItem item = (FileItem) CollectionUtils.find(items, new BeanPropertyValueEqualsPredicate("fieldName", "firstName"));

		user.setFirstName(item.getString());

		if (StringUtils.isEmpty(user.getFirstName())) {
			MessagesUtil.addMessage(request, MessagesUtil.ERROR, "Le prenom est obligatoire");
		}
	}

	/**
	 * Recupere le mot de passe dans la liste d'items.
	 * 
	 * @param request
	 *            Requete
	 * @param items
	 *            Liste d'items
	 * @param user
	 *            Utilisateur en cours de modification
	 */
	private void retreivePassword(final HttpServletRequest request, final Collection<FileItem> items, final User user) {
		FileItem item = (FileItem) CollectionUtils.find(items, new BeanPropertyValueEqualsPredicate("fieldName", "password"));

		user.setPassword(item.getString());
	}

	/**
	 * Recupere l'avatar dans la liste d'items.
	 * 
	 * @param request
	 *            Requete
	 * @param items
	 *            Liste d'items
	 * @param user
	 *            Utilisateur modifie
	 * @throws ServletException
	 *             Erreur de Servlet (Au chargement du contenu de l'avatar)
	 */
	private void retreiveAvatar(final HttpServletRequest request, final Collection<FileItem> items, final User user) throws ServletException {
		FileItem avatar = (FileItem) CollectionUtils.find(items, new BeanPropertyValueEqualsPredicate("fieldName", "avatar"));

		if (StringUtils.isNotEmpty(avatar.getName())) {
			if (!"image/jpeg".equals(avatar.getContentType())) {
				MessagesUtil.addMessage(request, MessagesUtil.ERROR, "La photo doit etre un fichier JPEG");

			} else if (avatar.getSize() > User.PHOTO_MAX_SIZE) {
				MessagesUtil.addMessage(request, MessagesUtil.ERROR, "La photo ne doit pas depasser "
						+ (Book.PHOTO_MAX_SIZE / SIZE_CONVERT) + " Ko");
			} else {
				user.setAvatar(avatar.get());
			}
		}
	}
}
